package com.wh.testDanLi;

/**
 * 懒汉式
 */
public class DanLiDemo2 {
    //通过标志位
    private static boolean wh=false;
    private DanLiDemo2(){
        synchronized (DanLiDemo3.class){
            if(!wh){
                wh=true;
            }else {
                throw new RuntimeException("不要试图利用反射来破化异常");
            }
            System.out.println(Thread.currentThread().getName()+"==>ok");
        }
    }
    private volatile static DanLiDemo2 danLiDemo2;

    public static DanLiDemo2 getInstance(){
        if(null == danLiDemo2){
            synchronized (DanLiDemo2.class){
                if(null == danLiDemo2){
                    danLiDemo2=new DanLiDemo2();//不是原子性操作
                    /**
                     * 1: 分配内存空间
                     * 2：执行构造方法，初始化对象
                     * 3：把这个对象指向这个空间
                     *
                     * 期望执行顺序：123
                     * 若为：132   当A线程执行到3；B线程也进入执行，此时一看对象已经指向一个空间，danLiDemo2!=null,则直接return
                     *                            此时danLiDemo2还没完成构造
                     *
                     */
                }
            }
        }
        return danLiDemo2;
    }
    //多线程并发
    public static void main(String[] args){
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                DanLiDemo2.getInstance();
            }).start();
        }
    }
}
